﻿//Di Carbone Carlo
//carbone05@gmail.com

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using Badge_Manager.Model;

namespace Badge_Manager.Controller
{
    public class ctrlAttivita
    {
        private Connector connector = Connector.Istance();
        protected List<DettaglioAttivita> elenco;
        protected Attivita attivita;

        public enum AttivitaEsistente
        {
            Esistente,
            NonEsistente,
            Errore
        }

        public ctrlAttivita(Attivita attivita)
        {
            this.attivita = attivita;
            if (attivita != null && attivita.DettagliAttivita != null)
                elenco = attivita.DettagliAttivita;
            if (attivita != null && (attivita.DettagliAttivita == null || attivita.DettagliAttivita.Count == 0))
                attivita.DettagliAttivita = GetDettagliByAttivitaId(attivita.Id);
        }

        public AttivitaEsistente VerificaAttivitaEsistente(Attivita attivita)
        {
            string query;
            query = @"SELECT Attivita.id, Corsi.codice, Corsi.nome,Corsi.datainizio
                    ,Corsi.datafine, Attivita.descrizione,Attivita.senzafine, Stanze.numero
                    FROM Attivita LEFT OUTER JOIN
                    Corsi ON Attivita.idcorso = Corsi.id LEFT OUTER JOIN
                    Stanze ON Attivita.idstanza = Stanze.id
                    WHERE Stanze.numero=" + attivita.Stanza.Numero + " "
                    + " and (Corsi.datafine > '" + attivita.Corso.DataInizio + "')";

            SqlDataAdapter com = new SqlDataAdapter(query, connector.Connessione);
            DataTable dt = new DataTable();
            com.Fill(dt);

            if (dt.Rows.Count > 0)
                return AttivitaEsistente.Esistente;
            else
                return AttivitaEsistente.NonEsistente;
        }

        /// <summary>
        /// Inserisce una nuova attivita in tabella Attivita
        /// </summary>
        /// <param name="attivita">Restituisce il numero di righe modificate;-1 se va in err</param>
        public virtual int Inserisci()
        {
            string query = "INSERT INTO Attivita VALUES"
                + "(@id,@idcorso,@descrizione, @senzafine, @idstanza)";
            try
            {
                SqlCommand insert = new SqlCommand(query, connector.Connessione);

                SqlParameter id = new SqlParameter();
                id.ParameterName = "@id";
                id.SqlDbType = SqlDbType.UniqueIdentifier;
                id.Value = attivita.Id;
                insert.Parameters.Add(id);

                SqlParameter idcorso = new SqlParameter();
                idcorso.ParameterName = "@idcorso";
                idcorso.SqlDbType = SqlDbType.UniqueIdentifier;
                idcorso.Value = attivita.Corso.Id;
                insert.Parameters.Add(idcorso);

                SqlParameter descrizione = new SqlParameter();
                descrizione.ParameterName = "@descrizione";
                descrizione.SqlDbType = SqlDbType.NVarChar;
                descrizione.Value = attivita.Descrizione;
                insert.Parameters.Add(descrizione);

                SqlParameter senzafine = new SqlParameter();
                senzafine.ParameterName = "@senzafine";
                senzafine.SqlDbType = SqlDbType.Bit;
                senzafine.Value = attivita.SenzaFine;
                insert.Parameters.Add(senzafine);

                SqlParameter idstanza = new SqlParameter();
                idstanza.ParameterName = "@idstanza";
                idstanza.SqlDbType = SqlDbType.UniqueIdentifier;
                idstanza.Value = attivita.Stanza.Id;
                insert.Parameters.Add(idstanza);

                return insert.ExecuteNonQuery();
            }
            catch
            {
                return -1;
            }
        }

        /// <summary>
        /// Modifica una riga
        /// </summary>
        /// <param name="attivita"></param>
        public int Update()
        {
            string query = "UPDATE Attivita SET "
                    + "idcorso = @idcorso, descrizione = @descrizione, senzafine = @senzafine, idstanza =  @idstanza"
                    + " WHERE id = @condizione";
            try
            {
                SqlCommand update = new SqlCommand(query, connector.Connessione);

                SqlParameter idcorso = new SqlParameter();
                idcorso.ParameterName = "@idcorso";
                idcorso.SqlDbType = SqlDbType.UniqueIdentifier;
                idcorso.Value = attivita.Corso.Id;
                update.Parameters.Add(idcorso);

                SqlParameter descrizione = new SqlParameter();
                descrizione.ParameterName = "@descrizione";
                descrizione.SqlDbType = SqlDbType.NVarChar;
                descrizione.Value = attivita.Descrizione;
                update.Parameters.Add(descrizione);

                SqlParameter senzafine = new SqlParameter();
                senzafine.ParameterName = "@senzafine";
                senzafine.SqlDbType = SqlDbType.Bit;
                senzafine.Value = attivita.SenzaFine;
                update.Parameters.Add(senzafine);

                SqlParameter idstanza = new SqlParameter();
                idstanza.ParameterName = "@idstanza";
                idstanza.SqlDbType = SqlDbType.UniqueIdentifier;
                idstanza.Value = attivita.Stanza.Id;
                update.Parameters.Add(idstanza);

                SqlParameter idattivita = new SqlParameter();
                idattivita.ParameterName = "@condizione";
                idattivita.SqlDbType = SqlDbType.UniqueIdentifier;
                idattivita.Value = attivita.Id;
                update.Parameters.Add(idattivita);

                return update.ExecuteNonQuery();
            }
            catch
            {
                return -1;
            }
        }

        /// <summary>
        /// Cancella un elemento dal database
        /// </summary>
        /// <param name="attivitaDaCancellare"></param>
        /// <returns>Numero di righe cancellate</returns>
        internal int Delete(Model.Attivita attivitaDaCancellare)
        {
            string query = " DELETE FROM Attivita WHERE id = @condizione";
            SqlCommand elimina = new SqlCommand(query, connector.Connessione);

            SqlParameter condizione = new SqlParameter();
            condizione.ParameterName = "@condizione";
            condizione.SqlDbType = SqlDbType.UniqueIdentifier;
            condizione.Value = attivitaDaCancellare.Id;
            elimina.Parameters.Add(condizione);

            return elimina.ExecuteNonQuery();
        }

        internal int Delete(Guid id)
        {
            string query = " DELETE FROM Attivita WHERE id = @condizione";
            SqlCommand elimina = new SqlCommand(query, connector.Connessione);

            SqlParameter condizione = new SqlParameter();
            condizione.ParameterName = "@condizione";
            condizione.SqlDbType = SqlDbType.UniqueIdentifier;
            condizione.Value = id;
            elimina.Parameters.Add(condizione);

            return elimina.ExecuteNonQuery();
        }

        /// <summary>
        /// Ricerca in tabella attivita (metodo completamente personalizzabile)
        /// </summary>
        /// <param name="campi"></param>
        /// <param name="condizione"></param>
        /// <param name="ordinamento"></param>
        /// <returns>Rest. un datatable</returns>
        public virtual DataTable Ricerca(string campi,
            string condizione = "1=1", string ordinamento = "")
        {
            string query;
            query = "SELECT " + campi
                + " FROM Attivita "
                + " WHERE " + condizione
                + " " + ordinamento;
            SqlDataAdapter com = new SqlDataAdapter(query, connector.Connessione);
            DataTable dt = new DataTable();
            com.Fill(dt);
            return dt;
        }

        public virtual DataTable Ricerca(string condizione = "1=1")
        {
            string query;
            query = @"SELECT Attivita.id AS Id, Corsi.codice AS Codice,
                    Corsi.nome AS Corso,Corsi.datainizio AS DataInizio,Corsi.datafine AS DataFine, Attivita.descrizione AS Descrizione, Stanze.numero AS Aula
                    FROM Attivita LEFT OUTER JOIN
                    Corsi ON Attivita.idcorso = Corsi.id LEFT OUTER JOIN
                    Stanze ON Attivita.idstanza = Stanze.id";
            query += " WHERE " + condizione;
            SqlDataAdapter com = new SqlDataAdapter(query, connector.Connessione);
            DataTable dt = new DataTable();
            com.Fill(dt);
            return dt;
        }

        /// <summary>
        /// Ricerca in tabella attivita con join(metodo completamente personalizzabile)
        /// </summary>
        /// <param name="campi"></param>
        /// <param name="condizione"></param>
        /// <param name="ordinamento"></param>
        /// <returns>Rest. un datatable</returns>
        public virtual DataTable SelectAttivitaCorsoStanzaAll()
        {
            string query;
            query = "SELECT Attivita.id,Corsi.datainizio AS CorsoInizio,Corsi.codice AS CodiceCorso,Corsi.nome AS NomeCorso, Attivita.descrizione AS DescrizioneAttivita, Attivita.senzafine AS SenzaFine, Stanze.numero AS NumeroStanza "
                    + "FROM  Attivita INNER JOIN "
                    + "Corsi ON Attivita.idcorso = Corsi.id INNER JOIN "
                    + "Stanze ON Attivita.idstanza = Stanze.id";

            SqlDataAdapter com = new SqlDataAdapter(query, connector.Connessione);
            DataTable dt = new DataTable();
            com.Fill(dt);
            return dt;
        }

        public List<DettaglioAttivita> GetDettagliByAttivitaId(Guid id)
        {
            List<DettaglioAttivita> listaDettagli = new List<DettaglioAttivita>();
            string query;
            query = "SELECT DettaglioAttivita.id, DettaglioAttivita.giorno AS Giorno, DettaglioAttivita.orainizio AS OraInizio, "
                + "DettaglioAttivita.orafine AS OraFine,DettaglioAttivita.minutiinizio AS MinutiInizio,DettaglioAttivita.minutifine AS MinutiFine "
                + "FROM  DettaglioAttivita "
                + "where DettaglioAttivita.idattivita = '" + id + "'"
                + " ORDER BY Giorno";
            SqlDataAdapter com = new SqlDataAdapter(query, connector.Connessione);
            DataTable dt = new DataTable();
            com.Fill(dt);
            foreach (DataRow dr in dt.Rows)
            {
                listaDettagli.Add(new DettaglioAttivita()
                {
                    Giorno = (DateTime)dr["Giorno"],
                    Id = (Guid)dr["id"],
                    MinutiFine = (int)dr["MinutiFine"],
                    MinutiInizio = (int)dr["MinutiInizio"],
                    OraFine = (int)dr["OraFine"],
                    OraInizio = (int)dr["OraInizio"]
                });
            }
            if (attivita != null && attivita.DettagliAttivita != null)
                attivita.DettagliAttivita = listaDettagli;
            return listaDettagli;
        }

        public List<Model.Attivita> GetAttivitaByCodiceTessera(string codice)
        {
            List<Model.Attivita> listaAttivitaPersona = new List<Model.Attivita>();
            DataTable dataTable = new DataTable();

            string query = @"SELECT     Attivita.id As idAttivita, Attivita.descrizione AS descrizioneAttivita, MIN(DettaglioAttivita.giorno) AS Min, { fn NOW() } AS Expr1, MAX(DettaglioAttivita.giorno) AS Max
                            FROM         Persone INNER JOIN
                            Attivita ON Persone.idattivita = Attivita.id INNER JOIN
                            Tessere ON Persone.idtessera = Tessere.id INNER JOIN
                            DettaglioAttivita ON Attivita.id = DettaglioAttivita.idattivita
                            WHERE     (Tessere.codice = '" + codice + @"')
                            GROUP BY Attivita.id, Attivita.descrizione
                            HAVING      ({ fn NOW() } < MAX(DettaglioAttivita.giorno)) AND (MIN(DettaglioAttivita.giorno) < { fn NOW() })";

            SqlDataAdapter sda = new SqlDataAdapter(query, connector.Connessione);
            sda.Fill(dataTable);

            foreach (DataRow riga in dataTable.Rows)
            {
                Model.Attivita attività = new Model.Attivita();
                attività.Id = (Guid)riga["idAttivita"];
                attività.Descrizione = (string)riga["descrizioneAttivita"];
                listaAttivitaPersona.Add(attività);
            }

            return listaAttivitaPersona;
        }

        public Attivita GetAttivitabyId(Guid id)
        {
            string sql =
  "SELECT  Stanze.id as StanzaId,Corsi.id as CorsoId,Corsi.nome, Attivita.descrizione, Attivita.senzafine, Stanze.numero, Attivita.id,Corsi.codice AS CodCorso "
                    + "FROM  Attivita INNER JOIN "
                    + "Corsi ON Attivita.idcorso = Corsi.id INNER JOIN "
                    + "Stanze ON Attivita.idstanza = Stanze.id "
                    + " WHERE Attivita.id='" + id + "'";
            SqlDataAdapter com = new SqlDataAdapter(sql, connector.Connessione);
            DataTable dt = new DataTable();
            com.Fill(dt);
            this.attivita = new Attivita();
            attivita.Id = id;
            attivita.Corso = new ctrlCorso().GetCorsoById((Guid)dt.Rows[0]["CorsoId"]);
            attivita.Descrizione = dt.Rows[0]["descrizione"].ToString();
            attivita.DettagliAttivita = GetDettagliByAttivitaId(id);
            attivita.SenzaFine = (bool)dt.Rows[0]["senzafine"];
            attivita.Stanza = new ctrlStanza().GetStanzaById((Guid)dt.Rows[0]["StanzaId"]);
            return this.attivita;
        }

        public Guid GetIdAttivitaByPersona(Persona persona)
        {
            string query = @"
                SELECT     Attivita.idcorso, Attivita.descrizione, Attivita.id, Attivita.senzafine, Attivita.idstanza, MAX(DettaglioAttivita.giorno) AS Expr1
                FROM         Persone INNER JOIN
                Attivita ON Persone.idattivita = Attivita.id INNER JOIN
                DettaglioAttivita ON Attivita.id = DettaglioAttivita.idattivita
                where Persone.id='" + persona.Id + @"'
                GROUP BY Attivita.idcorso, Attivita.descrizione, Attivita.id, Attivita.idstanza, Attivita.senzafine
                ORDER BY Expr1
                ";
            SqlDataAdapter sda = new SqlDataAdapter(query, connector.Connessione);
            DataTable dataTable = new DataTable();
            sda.Fill(dataTable);
            if (dataTable.Rows.Count > 0)
                return (Guid)dataTable.Rows[0]["Attivita.id"];
            else
                return Guid.Empty;
        }

        public Attivita GetAttivitaByPersona(Persona persona)
        {
            string query = @"
                SELECT     Attivita.idcorso, Attivita.descrizione, Attivita.id, Attivita.senzafine, Attivita.idstanza, MAX(DettaglioAttivita.giorno) AS Expr1
                FROM         Persone INNER JOIN
                Attivita ON Persone.idattivita = Attivita.id INNER JOIN
                DettaglioAttivita ON Attivita.id = DettaglioAttivita.idattivita
                where Persone.id='" + persona.Id + @"'
                GROUP BY Attivita.idcorso, Attivita.descrizione, Attivita.id, Attivita.idstanza, Attivita.senzafine
                ORDER BY Expr1
                ";
            SqlDataAdapter sda = new SqlDataAdapter(query, connector.Connessione);
            DataTable dataTable = new DataTable();
            sda.Fill(dataTable);
            if (dataTable.Rows.Count > 0)
                return GetAttivitabyId((Guid)dataTable.Rows[0]["Attivita.id"]);
            else
                return null;
        }

        public string getCorsoByPersona(Persona persona)
        {
            string sql;
            sql = @"SELECT Persone.id, Persone.nome, Persone.cognome, Corsi.nome AS NomeCorso
                    FROM Persone INNER JOIN
                    Attivita ON Persone.idattivita = Attivita.id INNER JOIN
                    Corsi ON Attivita.idcorso = Corsi.id
                    WHERE Persone.id='" + persona.Id + "'";

            SqlDataAdapter com = new SqlDataAdapter(sql, connector.Connessione);
            DataTable dt = new DataTable();
            com.Fill(dt);

            if (dt.Rows.Count > 0)
                return dt.Rows[0]["NomeCorso"].ToString();
            else
                return "";
        }
    }
}